import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.leon.HttpServlet;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

public class BootstrapBak {

    private Map<String, HttpServlet> servletMap = new HashMap<>();

    private void start() throws IOException {

        loadServletConfig();

        int corePoolSize = 10;
        int maximumPoolSize = 50;
        long keepAliveTime = 100L;
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory,
                handler
        );

        ServerSocket serverSocket = new ServerSocket(8080);

        /* 这一步就能实现对浏览器请求的一个基本响应
        while (true) {
            Socket socket = serverSocket.accept();
            String data = "Hello World!";
            String headerStr = HttpProtocolUtil.httpHeader200(data.getBytes().length) + data;
            OutputStream outputStream = socket.getOutputStream();
            outputStream.write(headerStr.getBytes());
            socket.close();
            outputStream.close();
        }*/

        /*  这一步把请求和响应封装成了 Request 和 Response
        while (true) {
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();

            try {
                Request request = new Request(inputStream);
                Response response = new Response(socket.getOutputStream());
                response.outputHtml(request.getUrl());
            } catch (Exception e) {
                e.printStackTrace();
            }

            socket.close();
        }*/

        /* 这一步能实现 动态 servlet 支持
        while (true) {
            Socket socket = serverSocket.accept();
            InputStream inputStream = socket.getInputStream();

            try {
                Request request = new Request(inputStream);
                Response response = new Response(socket.getOutputStream());

                // 请求路径包含，说明是一个 servlet 动态资源请求，否则尝试走静态资源处理过程
                if (servletMap.containsKey(request.getUrl())) {
                    HttpServlet httpServlet = servletMap.get(request.getUrl());
                    httpServlet.service(request, response);
                } else {
                    response.outputHtml(request.getUrl());
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            socket.close();
        }*/

        while (true) {
            Socket socket = serverSocket.accept();
            RequestProcessor processor = new RequestProcessor(socket, servletMap);
            threadPoolExecutor.execute(processor);
        }


    }

    private void loadServletConfig() {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
        SAXReader reader = new SAXReader();

        try {
            Document document = reader.read(resourceAsStream);
            Element rootElement = document.getRootElement();

            List<Element> nodes = rootElement.selectNodes("//servlet");
            for (int i = 0; i <nodes.size() ; i++) {
                Element element = nodes.get(i);
                Element servletNameEle = (Element)element.selectSingleNode("servlet-name");
                String servletName = servletNameEle.getStringValue();

                Element servletClassEle = (Element) element.selectSingleNode("servlet-class");
                String servletCls = servletClassEle.getStringValue();

                // 使用 xpath 表达式找到 servletName 对应的 servlet-mapping 元素，然后从中取得 url-pattern 的值
                Element servletMappingEle = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
                String urlPattern = servletMappingEle.selectSingleNode("url-pattern").getStringValue();

                // url-pattern 与 servlet 类的映射关系
                servletMap.put(urlPattern, (HttpServlet) Class.forName(servletCls).getDeclaredConstructor().newInstance());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*public static void main(String[] args) {
        try {
            new BootstrapBak().start();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }*/

}
